package com.shadt.pay.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.shadt.core.util.ConfigUtil;
import com.shadt.core.util.HttpsServiceRequest;
import com.shadt.core.util.IServiceRequest;
import com.shadt.core.util.RandomStringGenerator;
import com.shadt.core.util.Signature;
import com.shadt.core.util.XMLParser;
import com.shadt.pay.dao.ShadtAppDao;
import com.shadt.pay.dao.ShadtOrderDao;
import com.shadt.pay.entity.Pay_Shadt_App;
import com.shadt.pay.entity.Pay_Shadt_Order;
import com.shadt.pay.model.OrderQueryReceive;
import com.shadt.pay.model.OrderQueryReturn;
import com.shadt.pay.model.OrderReceive;
import com.shadt.pay.model.OrderReturn;
import com.shadt.pay.model.PayReceive;
import com.shadt.pay.service.PrePayService;
import com.shadt.pay.wechat.dao.WeChatOrderDao;
import com.shadt.pay.wechat.entity.Pay_WeChat_Order;
import com.shadt.pay.wechat.model.WeChatOrderQueryReceive;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
/**
 * shadt预支付业务层实现类
 * @author SongR
 *
 */
@Service
public class PrePayServiceImpl implements PrePayService{

	@Autowired
	ShadtAppDao appDao;
	@Autowired
	ShadtOrderDao orderDao;
	
	/**
	 * 实现shadt统一支付
	 */
	public String unifiedOrder(String reqXml,String ip) throws Exception{
		XStream xs = new XStream(new DomDriver("UTF-8",new XmlFriendlyNameCoder("-_", "_")));
		xs.alias("xml", OrderReceive.class);
		OrderReceive receive = (OrderReceive) xs.fromXML(reqXml);
		OrderReturn oReturn = new OrderReturn();
		if(null!=receive){
			Map<String,Object> params = new HashMap<String, Object>();
			params.put("mch_id", receive.getMch_id());
			params.put("app_id", receive.getAppid());
			Pay_Shadt_App shadtApp = appDao.get("from Pay_Shadt_App where shadt_mch_id = :mch_id and shadt_app_id = :app_id",params);
			if(null!=shadtApp){
				if (Signature.checkSign(reqXml, shadtApp.getShadt_app_key())) {
					Pay_Shadt_Order shadtOrder = null;
					for (Pay_Shadt_Order order : shadtApp.getShadtOrder()) {
						if(order.getOrder_tradeno().equals(receive.getOut_trade_no())){
							shadtOrder=order;
							break;
						}
					}
					if(null!=shadtOrder){
						switch (shadtOrder.getOrder_trade_status()) {
						case 0:
							oReturn.setReturn_code("SUCCESS");
							oReturn.setResult_code("SUCCESS");
							oReturn.setApp_id(receive.getAppid());
							oReturn.setMch_id(receive.getMch_id());
							oReturn.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
							oReturn.setSign(Signature.getSign(oReturn, shadtApp.getShadt_app_key()));
							break;
						case 1:
							oReturn.setReturn_code("SUCCESS");
							oReturn.setResult_code("FAIL");
							oReturn.setErr_code("OUT_TRADE_NO_USED");
							oReturn.setErr_code_des("商户订单号重复");
							oReturn.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
							oReturn.setSign(Signature.getSign(oReturn, shadtApp.getShadt_app_key()));
							break;
						case 2:
							oReturn.setReturn_code("SUCCESS");
							oReturn.setResult_code("FAIL");
							oReturn.setErr_code("ORDERCLOSED");
							oReturn.setErr_code_des("订单已关闭");
							oReturn.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
							oReturn.setSign(Signature.getSign(oReturn, shadtApp.getShadt_app_key()));
							break;
						case 9:
							oReturn.setReturn_code("SUCCESS");
							oReturn.setResult_code("FAIL");
							oReturn.setErr_code("ORDERPAID");
							oReturn.setErr_code_des("商户订单已支付");
							oReturn.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
							oReturn.setSign(Signature.getSign(oReturn, shadtApp.getShadt_app_key()));
							break;
						}
					}else{
						Pay_Shadt_Order order = new Pay_Shadt_Order();
						order.setOrder_noncestr(receive.getNonce_str());
						order.setOrder_sign(receive.getSign());
						order.setOrder_body(receive.getBody());
						order.setOrder_tradeno(receive.getOut_trade_no());
						order.setOrder_totalfee(Integer.parseInt(receive.getTotal_fee()));
						order.setOrder_terminalip(ip);
						order.setOrder_notifyUrl(receive.getNotify_url());
						order.setOrder_createTime(new Date());
						order.setOrder_trade_status(0);
						order.setShadtApp(shadtApp);
						orderDao.save(order);
						oReturn.setReturn_code("SUCCESS");
						oReturn.setResult_code("SUCCESS");
						oReturn.setApp_id(receive.getAppid());
						oReturn.setMch_id(receive.getMch_id());
						oReturn.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
						oReturn.setSign(Signature.getSign(oReturn, shadtApp.getShadt_app_key()));
					}
				}else{
					oReturn.setReturn_code("FAIL");
					oReturn.setResult_code("FAIL");
					oReturn.setErr_code("SIGNERROR");
					oReturn.setErr_code_des("签名失败");
				}
			}else{
				oReturn.setReturn_code("FAIL");
				oReturn.setResult_code("FAIL");
				oReturn.setErr_code("NOAUTH");
				oReturn.setErr_code_des("商户无此接口权限");
			}
		}else{
			oReturn.setReturn_code("FAIL");
			oReturn.setReturn_msg("参数异常");
		}
		XStream xss = new XStream(new DomDriver("UTF-8",new XmlFriendlyNameCoder("-_", "_")));
		xss.alias("xml", OrderReturn.class);
		return xss.toXML(oReturn);
	}

	/**
	 * 实现shadt支付请求
	 * @throws Exception 
	 */
	public Pay_Shadt_Order pay(String reqXml) throws Exception {
		PayReceive receive = (PayReceive)XMLParser.getObjectFromXml(reqXml, PayReceive.class);  
		Pay_Shadt_Order shadtOrder = null;
		if(null!=receive){
			Map<String,Object> params = new HashMap<String, Object>();
			params.put("mch_id", receive.getMch_id());
			params.put("app_id", receive.getAppid());
			Pay_Shadt_App shadtApp = appDao.get("from Pay_Shadt_App where shadt_mch_id = :mch_id and shadt_app_id = :app_id",params);
			if(null!=shadtApp){
				List<Pay_Shadt_Order> orders = shadtApp.getShadtOrder();
				for (Pay_Shadt_Order order : orders) {
					if(order.getOrder_tradeno().equals(receive.getOut_trade_no())){
						shadtOrder=order;
						shadtOrder.setRedirect_uri(receive.getRedirect_uri());
						orderDao.saveOrUpdate(shadtOrder);
						break;
					}
				}
			}else{
				
			}
		}else{
			
		}
		return shadtOrder;
	}

	
	
	@Autowired
	WeChatOrderDao wechatOrderDao;
	/**
	 * 实现shadt订单查询
	 */
	public String orderQuery(String reqXml) throws Exception{
//		OrderQueryReceive receive = (OrderQueryReceive)XMLParser.getObjectFromXml(reqXml, OrderQueryReceive.class);
		XStream xs = new XStream(new DomDriver("UTF-8",new XmlFriendlyNameCoder("-_", "_")));
		xs.alias("xml", OrderQueryReceive.class);
		OrderQueryReceive receive = (OrderQueryReceive) xs.fromXML(reqXml);
		OrderQueryReturn queryReturn = new OrderQueryReturn();//返回结果
		if(null!=receive){
			Map<String,Object> params = new HashMap<String, Object>();
			params.put("mch_id", receive.getMch_id());
			params.put("app_id", receive.getAppid());
			Pay_Shadt_App shadtApp = appDao.get("from Pay_Shadt_App where shadt_mch_id = :mch_id and shadt_app_id = :app_id",params);
			if(null!=shadtApp){
				if (Signature.checkSign(reqXml, shadtApp.getShadt_app_key())) {
					Pay_Shadt_Order shadtOrder = null;
					for (Pay_Shadt_Order order : shadtApp.getShadtOrder()) {
						if(order.getOrder_tradeno().equals(receive.getOut_trade_no())){
							shadtOrder=order;
							break;
						}
					}
					if(null!=shadtOrder){
						queryReturn.setAppid(shadtApp.getShadt_app_id());
						queryReturn.setMch_id(shadtApp.getShadt_mch_id());
						queryReturn.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
						if(shadtOrder.getOrder_trade_status()!=0){//订单已支付
							if(shadtOrder.getOrder_trade_type().equals("WECHAT")){//微信方式
								Map<String,Object> wechatorderparams = new HashMap<String, Object>();
								wechatorderparams.put("out_trade_no",shadtOrder.getOrder_tradeno());
								Pay_WeChat_Order wechatOrder = wechatOrderDao.get("from Pay_WeChat_Order where out_trade_no = :out_trade_no",wechatorderparams);
								if(null==wechatOrder){
									WeChatOrderQueryReceive wechatQuery = new WeChatOrderQueryReceive();
									wechatQuery.setAppid(shadtApp.getWeChatApp().getWechat_app_id());
									wechatQuery.setMch_id(shadtApp.getWeChatApp().getWechat_mch_id());
									wechatQuery.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
									wechatQuery.setOut_trade_no(shadtOrder.getOrder_tradeno());
									wechatQuery.setSign(Signature.getSign(wechatQuery,shadtApp.getWeChatApp().getWechat_app_key()));
									IServiceRequest is = new HttpsServiceRequest();
									String respXml = is.sendPost(ConfigUtil.get("wechatconfig", "orderqueryurl"), wechatQuery);
									XStream wechatOrderXs = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));// 解决XStream对出现双下划线的bug
									wechatOrderXs.alias("xml", Pay_WeChat_Order.class);
									wechatOrder = (Pay_WeChat_Order) wechatOrderXs.fromXML(respXml);
									wechatOrder.setId(UUID.randomUUID().toString());
									wechatOrderDao.save(wechatOrder);
								}
								queryReturn.setReturn_code(wechatOrder.getResult_code());
								queryReturn.setResult_code(wechatOrder.getResult_code());
								queryReturn.setTrade_type("WECHAT");
								queryReturn.setTrade_state(wechatOrder.getTrade_state());
								queryReturn.setTotal_fee(wechatOrder.getTotal_fee());
								queryReturn.setOut_trade_no(wechatOrder.getOut_trade_no());
								queryReturn.setTime_end(wechatOrder.getTime_end());
								queryReturn.setTrade_state_desc(wechatOrder.getTrade_state_desc());
							}
						}else{
							queryReturn.setReturn_code("SUCCESS");
							queryReturn.setResult_code("SUCCESS");
							queryReturn.setTrade_state("NOTPAY");
						}
						queryReturn.setSign(Signature.getSign(queryReturn,shadtApp.getShadt_app_key()));
					}else{
						queryReturn.setReturn_code("FAIL");
						queryReturn.setReturn_msg("订单不存在！");
					}
				}else{
					queryReturn.setReturn_code("FAIL");
					queryReturn.setReturn_msg("签名错误！");
				}
			}else{
				queryReturn.setReturn_code("FAIL");
				queryReturn.setReturn_msg("商户不存在！");
			}
		}else{
			queryReturn.setReturn_code("FAIL");
			queryReturn.setReturn_msg("参数错误！");
		}
		XStream xss = new XStream(new DomDriver("UTF-8",new XmlFriendlyNameCoder("-_", "_")));
		xss.alias("xml", OrderQueryReturn.class );
		String s =  xss.toXML(queryReturn);
		return s;
	}
	
}
